	
	/***********************************************************************************************
	
		Class: Encode.Blob							- sid: 1.0
		
		Api:
			obj	Blob				(bytes)				- sid: 1.0
			n		getSize			()						- sid: 1.0

			a		toArray			()						- sid: 1.0
			s		toString		()						- sid: 1.0
			
			n		tell				()						- sid: 1.0
			obj	seek				(i, mode)			- sid: 1.0
			b		eob					()						- sid: 1.0
			n		read				(bit, i)			- sid: 1.0
			obj	write				(n, bit, i)		- sid: 1.0
			obj	insert			(n, bit, i)		- sid: 1.0
			
	***********************************************************************************************/
//mettere Base64ForUrl 
//Modified Base64 for URLs replaces the '+' and '/' characters of standard Base64 with '-' and '_' respectively, so that these Base64 signatures no longer need to be URL-encoded

	
	//-------------------------------------------------------------------------------	 
	jsl.Class("jsl.Encode.Blob", {
		
		//-------------------------------------------------------------------------------	 
		__bytes: 	null,
		__idx:		0,
		
		//-------------------------------------------------------------------------------	 
		Blob: function(bytes) {
			var a, data, len
			
			if(arguments.length > 1)	throw jsl.ParamError()

			if(arguments.length) {
				
				jsl.validate(bytes, "al|s", "bytes")
				
				if(jsl.isString(bytes)) 
					for(a = 0, len = bytes.length, data = []; a < len; a++)
						data[a] = bytes.charCodeAt(a)
				else
					data = bytes
					
		//		for(a = 0, len = data.length; a < len; a++)
		//			if(!jsl.isNumber(data[a]) || data[a] < 0 || data[a] > 255)	throw jsl.ParamError("BadValue:bytes[" + a + "]")					
			}
			
			this.__bytes = data ? data.slice() : []
		},
		//-------------------------------------------------------------------------------	 
		getBytes: function() {
			if(arguments.length)	throw jsl.ParamError()
			return this.__bytes.slice()	
		},
		//-------------------------------------------------------------------------------	 
		getSize: function() {
			if(arguments.length)	throw jsl.ParamError()
			return this.__bytes.length	
		},
		//-------------------------------------------------------------------------------	 
		insert: function(v, idx, n) {
//			if(arguments.length)	throw jsl.ParamError()
			this.__bytes.splice(idx, 0, v)	
		},		
		//-------------------------------------------------------------------------------	 
		slice: function(s, e) {
//			if(arguments.length)	throw jsl.ParamError()
			return new jsl.Encode.Blob(this.__bytes.slice(s, e || 100000000))	
		},		
		//-------------------------------------------------------------------------------	 
		read: function(idx, n) {
//			if(arguments.length)	throw jsl.ParamError()
			return this.__bytes[idx]	
		},		
		//-------------------------------------------------------------------------------	 
		//append?
		push: function(v, n) {
			var pow, idx, bytes, i, bit, isN
			
			if(!arguments.length || arguments.length > 2)	throw jsl.ParamError()
//			jsl.validate(v, "i|al", "v")
			
			isN = true// jsl.isNumber(v)
			
			if(arguments.length === 2)	{
				if(!isN)	throw jsl.ParamError("NotRequired:n")
	//			jsl.validate(n, "i[1-32]","n")			
//				if(Math.pow(2, n) - 1 < v) throw jsl.ParamError("BadValue:v")
			}
			
			if(!isN) {
				//gestire se this.__idx
				for(var a = 0, l = v.length; a < l; a++) {
					//if 0 a 255 throw
					this.__bytes.push(v[a])
				}
			}
			else {									
			
				pow		= Math.pow
				idx 	= this.__idx
				bytes = this.__bytes
				i			= n || 8
				
				if(idx) {			
					bit = 8 - idx
					
					if(i - bit >= 0)	bytes[bytes.length - 1] |= v >> n - bit						
					else							bytes[bytes.length - 1] |= v << bit - i 
					
					i -= bit
				}
				
				while(i > 0) {			
					if(i > 8) 	bytes.push((v & (pow(2, i) - 1)) >> i - 8)
					else				bytes.push((v & (pow(2, i) - 1)) << 8 - i)					
					i -= 8
				}			 
				
				this.__idx = (idx + n) % 8		
			}
		},
		//-------------------------------------------------------------------------------	 
		getIterator: function() { 
			var it
			var obj = this
			
			it = { __idx: 0, __name: "jsl.Encode.BlobIterator" }
			
 		//-------------------------------------------------------------------------------
			it.hasNext = function() {
				try {
					if(arguments.length)	throw jsl.ParamError()			
					return this.__idx < (obj.__bytes.length - 1) * 8 + obj.__idx 
				}
				catch(e) {
					jsl.throwError(e, this, arguments)
				}
			}
  		//-------------------------------------------------------------------------------
			it.next = function(n) {
				try {
					var pow, idx, bytes, i, ix, bit, v, ib
					
		//			if(arguments.length > 1) 	throw jsl.ParamError()
//					if(arguments.length)			jsl.validate(n, "i[1-32]", "n")					
										
	//				if(this.__idx + n - 1 > obj.__bytes.length * 8 + obj.__idx)	throw jsl.EndOfIterationError()	

					pow		= Math.pow
					idx 	= this.__idx
					ix		= idx % 8
					bytes = obj.__bytes
					ib		= ~~(idx / 8)
					i			= n
					v			= 0
					
					if(ix) {			
						bit = 8 - ix
						
						if(i - bit >= 0)	v =  bytes[ib++] & (pow(2, bit) - 1)						
						else							v = (bytes[ib++] >> bit - i) & (pow(2, i) - 1) 
						
						i -= bit
					}
					
					while(i > 0) {			
						if(i > 8) 	v = (v << 8) +  bytes[ib++]
						else				v = (v << i) + (bytes[ib++] >> (8 - i))					
						i -= 8
					}			 
					
					this.__idx = idx + n	

					return v
				}
				catch(e) {
					jsl.throwError(e, this, arguments)
				}
			}
						
			return it
		},		
		//-------------------------------------------------------------------------------	 
		toString: function() { 
			//@sys: v8Cgi 0.9.0 - RangeError: Maximum call stack size exceeded (perhaps too many arguments)
			//return String.fromCharCode.apply(String, this.__bytes) 
			var txt = [], c = 0, fcc
			
			fcc = String.fromCharCode
			for(var a = 0; a < this.__bytes.length; a += 20000)
				txt[c++] = fcc.apply(String, this.__bytes.slice(a, a+ 20000))
				return txt.join("")
		}
	})	

		